﻿using System;
using System.Linq;
using System.Transactions;
using KillBill.Business.Entities;
using KillBill.Data.DataAccess;
using KillBill.Services.DTO;
using KillBill.Business.Entities.ListEntities;

namespace KillBill.Business.Modules.Products
{
    public class ProductsManager
    {
        private readonly KillBillEntities _context;

        public ProductsManager()
        {
            _context = new KillBillEntities();
        }

        #region Product Basic Operations

        public ProductList GetProducts()
        {
            var list = new ProductList();
            try
            {
                list.Products = _context.Product.Include("Provider").ToList();
                list.Success = true;
                list.Messages.Add("Lista de productos fue consultada con éxito.");
                
            }
            catch (Exception ex)
            {
                list.Success = false;
                list.Messages.Add("La lista de productos no puede ser obtenida.");
                list.Messages.Add(ex.Message);
            }
            return list;
        }

        public ProductList FindProducts(string value)
        {
            if (value == "") return GetProducts();
            var list = new ProductList();
            try
            {
                list.Success = true;
                list.Messages.Add("Lista de productos obtenida exitosamente.");
                list.Products = _context
                    .Product
                    .Include("Provider")
                    .Where(p => (
                        p.Provider.Name + " " +
                        p.Name + " " +
                        p.Description + " " +
                        p.LastPrice + " " +
                        p.Stock + " " +
                        p.StockMin + " " +
                        p.StockMax
                    ).Contains(value))
                    .ToList();
            }
            catch (Exception ex)
            {
                list.Success = false;
                list.Messages.Add("La lista de cleintes no puedo ser obtenida.");
                list.Messages.Add(ex.Message);
            }
            return list;
        }

        public Product AddProduct(Product product)
        {
            try
            {
                using (var ts = new TransactionScope())
                {
                    product.ModifiedDate = DateTime.Now;
                    _context.Product.AddObject(product);
                    _context.SaveChanges();
                    product.Messages.Add("El producto ha sido agregado con éxito");
                    product.Success = true;
                    ts.Complete();
                    return product;
                }
            }
            catch (Exception ex)
            {
                product.Success = false;
                product.Messages.Add("Ocurrió un error al agregar el producto.");
                product.Messages.Add(ex.Message);
                return product;
            }
        }

        public Product UpdateProduct(Product product)
        {
            try
            {
                using (var ts = new TransactionScope())
                {
                    product.ModifiedDate = DateTime.Now;
                    _context.Product.ApplyChanges(product);
                    _context.SaveChanges();
                    product.Success = true;
                    product.Messages.Add("El producto ha sido actualizado");
                    ts.Complete();
                    return product;
                }
            }
            catch (Exception ex)
            {
                product.Success = false;
                product.Messages.Add("Ocurrió un error al actualizar el producto.");
                product.Messages.Add(ex.Message);
                return product;
            }
        }

        public KillBillDTO DeleteProduct(Product product)
        {
            var killBillDto = new KillBillDTO();
            try
            {
                using (var ts = new TransactionScope())
                {
                    product.ModifiedDate = DateTime.Now;
                    product.IsActive = false;
                    _context.Product.ApplyChanges(product);
                    _context.SaveChanges();
                    killBillDto.Success = true;
                    killBillDto.Messages.Add("El producto ha sido eliminado con éxito");
                    ts.Complete();
                    return killBillDto;
                }
            }
            catch (Exception ex)
            {
                killBillDto.Messages.Clear();
                killBillDto.Success = false;
                killBillDto.Messages.Add("Ocurrió un error al borrar el producto.");
                killBillDto.Messages.Add(ex.Message);
                return killBillDto;
            }
        }

        public ProductList GetProductList()
        {
            var productList = new ProductList();
            try
            {
                productList.Products = _context.Product.Top("10").OrderBy(p => p.Name) .ToList();
                
                productList.Messages.Add("Los productos han sido consultados con exito");
                productList.Success = true;
                return productList;
            }
            catch (Exception ex)
            {
                productList.Messages.Clear();
                productList.Messages.Add("Ocurrió un error al obtener lista de productos.");
                productList.Messages.Add(ex.Message);
                productList.Success = false;
                return productList;
            }
        }

        public ProductList FindProduct(string productName)
        {
            var productList = new ProductList();
            try
            {

                if(productName != string.Empty)
                {
                    productList.Products = _context.Product
                    .Include("Provider")
                    .Where(p => p.Name.Contains(productName)).ToList();
                }
                else
                {
                    productList.Products = _context.Product.Include("Provider").Top("20").ToList();
                }

                productList.Messages.Add(productList.Products.Count == 0
                                             ? "Producto no encontrado."
                                             : "Producto encontrado.");

                productList.Success = true;

                return productList;
            }
            catch (Exception ex)
            {
                productList.Success = false;
                productList.Messages.Add("Ocurrió un error al obtener la lista de productos.");
                productList.Messages.Add(ex.Message);
                return productList;
            }
        }

        public Product FindProductById(int productId)
        {
            Product product;
            try
            {
                product = _context.Product
                .Include("Provider")
                .Include("Provider.Person")
                .First(p => p.ProductID == productId);

                if (product == null)
                {
                    product = new Product();
                    product.Messages.Add("Producto no encontrado");
                }
                else
                {
                    product.Messages.Add("Cliente encontrado");
                }
                product.Success = true;
                return product;
            }
            catch (Exception ex)
            {
                product = new Product();
                product.Messages.Add("Ocurrió un error al buscar el empleado.");
                product.Messages.Add(ex.Message);
                product.Success = false;
                return product;
            }
        }

        #endregion
    }
}
